package com.alibaba.otter.node.etl.autoconfigure;

import com.alibaba.otter.node.common.autoconfigure.NodeProperties;
import com.alibaba.otter.node.common.config.ConfigClientService;
import com.alibaba.otter.node.etl.common.io.download.DataRetrieverFactory;
import com.alibaba.otter.node.etl.common.pipe.impl.RowDataPipeDelegate;
import com.alibaba.otter.node.etl.common.pipe.impl.http.AttachmentHttpPipe;
import com.alibaba.otter.node.etl.common.pipe.impl.http.RemoteUrlBuilder;
import com.alibaba.otter.node.etl.common.pipe.impl.http.RowDataHttpPipe;
import com.alibaba.otter.node.etl.common.pipe.impl.http.archive.ArchiveBean;
import com.alibaba.otter.node.etl.common.pipe.impl.memory.RowDataMemoryPipe;
import com.alibaba.otter.node.etl.common.pipe.impl.rpc.RowDataRpcPipe;
import org.springframework.aop.target.CommonsPool2TargetSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(NodeProperties.class)
public class NodePipeAutoConfiguration {

    private final NodeProperties nodeProperties;

    public NodePipeAutoConfiguration(NodeProperties nodeProperties) {
        this.nodeProperties = nodeProperties;
    }

    @Bean
    public RowDataMemoryPipe rowDataMemoryPipe() {
        RowDataMemoryPipe rowDataMemoryPipe = new RowDataMemoryPipe();
        rowDataMemoryPipe.setRetry(3);
        rowDataMemoryPipe.setTimeout(60000L);
        rowDataMemoryPipe.setDownloadDir(nodeProperties.getDownloadDir());
        return rowDataMemoryPipe;
    }


    @Bean
    public AttachmentHttpPipe attachmentHttpPipe(RemoteUrlBuilder remoteUrlBuilder,
                                                 DataRetrieverFactory dataRetrieverFactory,
                                                 ConfigClientService configClientService) {
        AttachmentHttpPipe attachmentHttpPipe = new AttachmentHttpPipe();
        attachmentHttpPipe.setRemoteUrlBuilder(remoteUrlBuilder);
        attachmentHttpPipe.setDataRetrieverFactory(dataRetrieverFactory);
        attachmentHttpPipe.setConfigClientService(configClientService);
        attachmentHttpPipe.setHtdocsDir(nodeProperties.getHtDocDir());
        attachmentHttpPipe.setDownloadDir(nodeProperties.getDownloadDir());
        return attachmentHttpPipe;
    }


    @Bean
    public RowDataPipeDelegate rowDataPipeDelegate(RowDataMemoryPipe rowDataMemoryPipe,
                                                   AttachmentHttpPipe attachmentHttpPipe,
                                                   RowDataHttpPipe rowDataHttpPipe,
                                                   RowDataRpcPipe rowDataRpcPipe,
                                                   ConfigClientService configClientService) {
        RowDataPipeDelegate rowDataPipeDelegate = new RowDataPipeDelegate();
        rowDataPipeDelegate.setRowDataMemoryPipe(rowDataMemoryPipe);
        rowDataPipeDelegate.setAttachmentHttpPipe(attachmentHttpPipe);
        rowDataPipeDelegate.setRowDataHttpPipe(rowDataHttpPipe);
        rowDataPipeDelegate.setRowDataRpcPipe(rowDataRpcPipe);
        rowDataPipeDelegate.setConfigClientService(configClientService);
        return rowDataPipeDelegate;
    }

    @Bean
    public RemoteUrlBuilder remoteUrlBuilder(ConfigClientService configClientService) {
        RemoteUrlBuilder remoteUrlBuilder = new RemoteUrlBuilder();
        remoteUrlBuilder.setConfigClientService(configClientService);
        remoteUrlBuilder.setUrlFormat("http://{0}:{1}/download/{2}");
        return remoteUrlBuilder;
    }

    @Bean
    public RowDataRpcPipe rowDataRpcPipe() {
        return new RowDataRpcPipe();
    }

    @Bean
    public RowDataHttpPipe rowDataHttpPipe(RemoteUrlBuilder remoteUrlBuilder) {
        RowDataHttpPipe rowDataHttpPipe = new RowDataHttpPipe();
        rowDataHttpPipe.setTimeout(60000L);
        rowDataHttpPipe.setPeriod(60000L);
        rowDataHttpPipe.setHtdocsDir(nodeProperties.getHtDocDir());
        rowDataHttpPipe.setDownloadDir(nodeProperties.getDownloadDir());
        rowDataHttpPipe.setRemoteUrlBuilder(remoteUrlBuilder);
        return rowDataHttpPipe;
    }

    @Bean
    public DataRetrieverFactory dataRetrieverFactory() {
        return new DataRetrieverFactory();
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public ArchiveBean archiveBeanTarget() {
        ArchiveBean archiveBean = new ArchiveBean();
        archiveBean.setPoolSize(5);
        return archiveBean;
    }

    @Bean
    public CommonsPool2TargetSource archiveBeanTargetSource() {
        CommonsPool2TargetSource commonsPool2TargetSource = new CommonsPool2TargetSource();

        commonsPool2TargetSource.setMinIdle(1);
        commonsPool2TargetSource.setMaxSize(-1);
        commonsPool2TargetSource.setTimeBetweenEvictionRunsMillis(60000);
        commonsPool2TargetSource.setMinEvictableIdleTimeMillis(60000);
        commonsPool2TargetSource.setTargetBeanName("archiveBeanTarget");

        return commonsPool2TargetSource;
    }
}
